package com.xuxueli.crawler.test;

import com.xuxueli.crawler.XxlCrawler;
import com.xuxueli.crawler.annotation.PageFieldSelect;
import com.xuxueli.crawler.annotation.PageSelect;
import com.xuxueli.crawler.conf.XxlCrawlerConf;
import com.xuxueli.crawler.parser.PageParser;
import com.xuxueli.crawler.util.FileUtil;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

/**
 * @author: zmh
 * @create: 18-9-19
 * @description: 通过Cookie进入页面，需要实现登录
 **/
public class CrawlDoban {

    @PageSelect(cssQuery = "body")
    public static class PageVo {

        @PageFieldSelect(cssQuery = "body")
        private String title;

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }
    }

    public static void main(String[] args) throws InterruptedException {
        //通过cookie进行登录
    HashMap<String,String> cookie = new HashMap<>();
        cookie.put("dbcl2","184702613:o215hwrJ1e4");
                cookie.put("path","/");
                cookie.put("domain",".douban.com");
                cookie.put("as","deleted");
                cookie.put("max-age","0");
        XxlCrawler crawler = new XxlCrawler.Builder()
                .setUrls("https://www.douban.com/people/conanemily/contacts")
//                .setUrls("https://www.douban.com")
                .setWhiteUrlRegexs("https://www.douban.com/people/conanemily/contacts")
                .setThreadCount(1)
                .setFailRetryCount(2)
                .setPauseMillis(1000)
                .setIfPost(false)
                .setCookieMap(cookie)
                .setPageParser(new PageParser<CrawlLogin.PageVo>() {
                    @Override
                    public void parse(Document html, Element pageVoElement, CrawlLogin.PageVo pageVo) {
                        // 解析封装 PageVo 对象
                        System.out.println(html.html());
                    }
                })
                .build();
        System.out.println("start");
        crawler.start(true);
        System.out.println("end");
    }



    /**
     * 下载图片地址
     *
     * @param imageUrl
     * @param imageSaveUrl
     */
    private static void downloadImage(String imageUrl, String imageSaveUrl) {
        String fileName = FileUtil.getFileNameByUrl(imageUrl, null);
        boolean ret = FileUtil.downFile(imageUrl, XxlCrawlerConf.TIMEOUT_MILLIS_DEFAULT, imageSaveUrl, fileName);
        System.out.println("down images " + (ret ? "success" : "fail") + "：" + imageUrl);
    }

    private static void openLoadImage(String imageSaveUrl) {
        FileUtil.getFileNameByUrl(imageSaveUrl, null);
    }

    private static HttpClient httpClient = new DefaultHttpClient();

    private static String getImgID() {
        //Json的地址[数据中包含验证码的地址]
        String src = "https://www.douban.com/j/misc/captcha";
        HttpGet httpGet = new HttpGet(src);
        String token = "";
        try {
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            //将json数据转化为map，对应的是key，value的形式。不理解json数据的，请看我前面的关于json解析的博客
            String content = EntityUtils.toString(entity, "utf-8");
            Map<String, String> mapList = getResultList(content);
            token = mapList.get("token");
            //获取验证码的地址
            String url = "https:" + mapList.get("url");
            //下载验证码并存储到本地
            downloadImage(url, "./");
            //手动验证码识别
            System.out.println(token);
            System.out.println(url);
            System.out.println(content);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return token;
    }

    public static Map<String, String> getResultList(String content) {
        Map<String, String> maplist = new HashMap<String, String>();
        try {
            JSONObject jo = new JSONObject(content.replaceAll(",\\\"r\\\":false", ""));
            Iterator it = jo.keys();
            String key = "";
            String value = "";
            while (it.hasNext()) {
                key = (String) it.next();
                value = jo.getString(key);
                maplist.put(key, value);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return maplist;
    }

    //主登录入口
    public static void loginDouban() {
        String login_src = "https://accounts.douban.com/login";
        //输入用户名及密码
        String form_email = "1246411835@qq.com";
        String form_password = "born199505111310";
        //获取验证码
        String captcha_id = getImgID();
        String login = "登录";
        String source = "index_nav";//登陆的source
        String captcha_solution = "";
        //输入验证码
        System.out.println("请输入验证码：");
        BufferedReader buff = new BufferedReader(new InputStreamReader(System.in));
        try {
            captcha_solution = buff.readLine();
            System.out.println("输入验证码结束：-----");
        } catch (IOException e) {
            e.printStackTrace();
        }
//        构建参数，即模拟需要输入的参数。这部分通过抓包获得。不会抓包的请看我之前写的一些博客
        List<NameValuePair> list = new ArrayList<NameValuePair>();
        list.add(new BasicNameValuePair("form_email", form_email));
        list.add(new BasicNameValuePair("form_password", form_password));
        list.add(new BasicNameValuePair("captcha-solution", captcha_solution));
        list.add(new BasicNameValuePair("captcha-id", captcha_id));
        list.add(new BasicNameValuePair("login", login));
        HttpPost httpPost = new HttpPost(login_src);
        try {
            //向后台请求数据,登陆网站
            httpPost.setEntity(new UrlEncodedFormEntity(list));
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity, "utf-8");
            System.out.println(result);
            //进行请求其他网址
//            https://www.douban.com/people/conanemily/contacts
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}
